#include "gsedialog.h"
#include <QFile>
#include <QProgressBar>
#include <QtNetwork/QtNetwork>
#include <QTextStream>
#include <QRegExp>
#include <QDir>

gseDialog::gseDialog(QWidget *parent) :
    QMainWindow(parent)
{
    setupUi(this);

    settings = new QSettings("Cydeamon's Projects", "Great Soviet Encyclopedia");

    version  = "1.2.1";
    settingsDialog = new SettingsDialog(this);

    loadSettings();

    /* show SplashScreen */
    QPixmap pixmap("./images/splashscreen.jpg");
    splashscreen = new QSplashScreen(pixmap);

    QProgressBar bar(splashscreen);
    bar.setMaximum(74307);
    bar.setValue(0);
    bar.setGeometry(3, 34, splashscreen->width() / 1.5, 20);

    splashscreen->show();

    /* including files */
    char fileName;
    QString toSplashscreen;
    QFile file;
    QString key, value;

    for( int i = 0; i < 33; i++) // getting content of file
    {
        if( i < 9)
            fileName = i + 1 + 48;
        else            // Skip unnecessary symbols
            fileName = i + 56;

        toSplashscreen = QString("%1.txt")
                .arg(fileName);
        showOnSplashscreen("Загрузка " + toSplashscreen);
        splashscreen->setFocus();

        file.setFileName( QString("./enc/%1.txt").arg(fileName));
        file.open(QFile::ReadOnly);

        int count = 0;      // Подсчет количества статей для прогресс-бара

        if( file.exists() )
        {
            do
            {
                value =file.readLine(); // Получение строки

                bool bracket = false;       // Была ли встречена скобка в строке

                for(register int j = 0; value[j] != '\n'; j++)    // Получение key (темы)
                {
                    value[j].toLower();     // В файле все названия тем пишутся прописными

                    if( value[j] == '(')
                        bracket = true;
                    else if( value[j] == ')')
                        bracket = false;

                    if( !bracket && value[j] == ',')    // Если скобка была или она закрылась, то
                    {
                        count++;
                        break;                          // начать получение статьи (value)
                    }

                    key += value[j];
                }
                value.remove(0, key.size() + 2);    // Получение value (статьи)

                if( key[key.size() - 1] == ' ' ) // Если нужно..
                    key.remove(key.size()-1, 1); // .. убрать лишний пробел в конце темы
                if( value[0] == ' ')
                    value.remove( 0, 1);         // .. убрать лишний пробел в начале статьи

                key      = key      .toLower();
                key[0]   = key[0]   .toUpper();
                value[0] = value[0] .toUpper();

                for( register int j = 0; j < key.size(); j++) // toUpper for first letter of words in key
                {
                    if( key[j] == ' ' || key[j] == '(')
                        key[j+1] = key[j+1].toUpper();
                }
                themeList->addItem(key);         // adding to list
                encyclopedia.insert(key, value); // adding to QMap

                bar.setValue( bar.value() + 1) ; // Обновляем прогрессбар

                key.clear();    // clear necessary variables
                value.clear();

            } while( !file.atEnd());

        }
        else
        {
            QMessageBox::warning(this, "Ошибка!",
                                 QString("Файл \"%1\" не найден").arg( file.fileName() )
                                 ,QMessageBox::Ok);;
            exit(0);
        }

        file.close();
    }

    showOnSplashscreen("Идет загрузка и применение настроек");
    /* Connect'ы */
    connect( actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));


    connect( settingsDialog->articleComboBox,     SIGNAL( currentFontChanged     ( QFont)),
                                                  SLOT  ( changeFont_articleText()));
    connect( settingsDialog->themeList_ComboBox,  SIGNAL( currentFontChanged     ( QFont)),
                                                  SLOT  ( changeFont_themeList()));


         connect( settingsDialog->articleText_fontSize_spinBox,
                 SIGNAL(valueChanged(int)), SLOT( changeFont_articleText()));
         connect( settingsDialog->themeList_fontSize_spinBox,
                 SIGNAL(valueChanged(int)), SLOT( changeFont_themeList()));

         connect( settingsDialog->default_article_checkbox,
                 SIGNAL(toggled(bool)),     SLOT( changeFont_articleText()));
         connect( settingsDialog->default_themeList_check,
                 SIGNAL(toggled(bool)),     SLOT( changeFont_themeList()));

    // ----
     connect( settingsDialog->previewCheckbox, SIGNAL(toggled(bool)), SLOT(previewCheckbox_isToggled(bool)));
     connect( settingsDialog->buttonBox, SIGNAL(accepted()), SLOT( settingsDialog_accepted()) );
     connect( settingsDialog->buttonBox, SIGNAL(rejected()), SLOT( settingsDialog_rejected()) );


    splashscreen->hide();
    setFocus();
    statusbar->showMessage( "Все файлы загружены. Теперь можно работать с программой", 5000);

}

void gseDialog::previewCheckbox_isToggled(bool checked)
{
    if( checked )
    {
        changeFont_articleText();
        changeFont_themeList();
    }
    else
    {
        articleText->setFont( current_articleText_font );
        themeList->setFont( current_themeList_font );
    }
}

void gseDialog::showOnSplashscreen( QString msg)
{

    splashscreen->showMessage( "Great Soviet Encyclopedia\n" + msg,// Сообщение
                              Qt::AlignTop | Qt::AlignLeft,       // Выравнивание
                              QColor("black"));

    QApplication::processEvents();
}

void gseDialog::on_searchButton_clicked()
{
    if(( searchLine->text()[0] <= 'Z' && searchLine->text()[0] >= 'A' ) ||
       ( searchLine->text()[0] <= 'z' && searchLine->text()[0] >= 'a' ))
    {
        statusbar->showMessage( "Неверный запрос. В GSE только русскоязычные статьи", 5000);
        searchLine->clear();
        return;
    }

    statusbar->showMessage( QString( "Идет поиск \"" + searchLine->text() + "\""));
    QChar firstLetter = searchLine->text().at(0).toUpper();   // first letter of search

    themeList->clear();

    iter = encyclopedia.begin();
    iter = encyclopedia.find( QString(searchLine->text()).at(0) );

    if( iter == encyclopedia.end() )
    {
        statusbar->showMessage( "Ничего не найдено", 5000 );
        return;
    }
    while( firstLetter == QString( iter.key() ).at(0))
    {
        if( iter != encyclopedia.end())
            iter++;
        else
            break;

        if ( findInString( searchLine->text(), iter.key()) ) // returns true, if founded
           themeList->addItem( iter.key());

    }
    if( themeList->count() == 0)
        statusbar->showMessage( "Ничего не найдено", 5000 );
    else
        statusbar->showMessage( "Поиск завершен", 1000);
}

bool gseDialog::findInString(QString whatToSearch, QString whereSearch)
{
    for( register int i = 0; i < whatToSearch.size(); i++)
       if( whereSearch[i] != whatToSearch[i])
           return false;

    return true;
}

void gseDialog::on_themeList_clicked()
{
    iter = encyclopedia.begin();
    iter = encyclopedia.find( themeList->currentItem()->text() );
    articleText->setText( iter.value() );
}

void gseDialog::on_actionSettings_triggered()
{
    showMaximized();
    settingsDialog->setFontSettings(current_themeList_font  , themeList_isDefault,
                                    current_articleText_font, articleText_isDefault);

    settingsDialog->show();
}

void gseDialog::on_actionAbout_GSE_2_triggered()
{
    aboutDialog = new AboutGSE_dialog( this );
    aboutDialog->show();
}

void gseDialog::on_actionCheck_for_updates_2_triggered() // Проверка на обновление
{
    system("wget http://cydeamonstools.vv.si/apps/gse_version");
    int cat_ret = system("cat ./gse_version");

    if( cat_ret )
        QMessageBox::warning(this, "Проверка на наличие обновлений", "Ошибка при загрузке"
                                 , QMessageBox::Ok);
    else
    {
        QFile gse_version("gse_version");
        gse_version.open(QFile::ReadOnly);

        QString ver = gse_version.readLine();
        ver = ver.remove('\n');

        if( ver == version )
            QMessageBox::information(this,"Проверка на наличие обновлений", "Обновление не требуется",
                                     QMessageBox::Ok);
        else
            QMessageBox::information(this,"Проверка на наличие обновлений",
                                     "Имеется <a href=http://code.google.com/p/greatsovietencyclopedia" \
                                     ">новая версия</a>",
                                     QMessageBox::Ok);

        gse_version.remove();   // Удаляем файл
        gse_version.close();
    }

    //TODO: check_for_updates: В файле gse_version передать ссылку на инсталлятор
}

/* -------------- Диалог Настроек ------------- */
void gseDialog::changeFont_articleText()
{
    if( settingsDialog->previewCheckbox->isChecked() )
    {
        statusbar->showMessage("Идет применение настроек. Подождите...");

        if( settingsDialog->default_article_checkbox->isChecked())
            articleText->setFont( QFont() );
        else
        {
            QFont font = settingsDialog->articleComboBox->currentFont();
            font.setPointSize( settingsDialog->articleText_fontSize_spinBox->value() );

            articleText->setFont( font );
        }

        statusbar->clearMessage();
    }
}

void gseDialog::changeFont_themeList()
{
    if( settingsDialog->previewCheckbox->isChecked() )
    {
        statusbar->showMessage( "Идет применение настроек. Подождите...");

        if( settingsDialog->default_themeList_check->isChecked())
                themeList->setFont( QFont() );
        else
        {
            QFont font = settingsDialog->themeList_ComboBox->currentFont();
            font.setPointSize( settingsDialog->themeList_fontSize_spinBox->value() );

            themeList->setFont( font );
        }

        statusbar->clearMessage();
    }
}

void gseDialog::settingsDialog_accepted()
{
    current_articleText_font = QFont( settingsDialog->articleComboBox->currentText(),
                                      settingsDialog->articleText_fontSize_spinBox->value());
    articleText_isDefault = settingsDialog->default_article_checkbox->isChecked();

    current_themeList_font   = QFont( settingsDialog->themeList_ComboBox->currentText(),
                                      settingsDialog->themeList_fontSize_spinBox->value());
    themeList_isDefault   = settingsDialog->default_themeList_check->isChecked();


    articleText->setFont(current_articleText_font);
    themeList->setFont(current_themeList_font);
    saveSettings();             // Сохранение настроек

    settingsDialog->close();
}

void gseDialog::settingsDialog_rejected()
{
    themeList   ->setFont( current_themeList_font   );
    articleText ->setFont( current_articleText_font );

    settingsDialog->close();
}

void gseDialog::saveSettings()
{
    settings->beginGroup("fonts");
    settings->setValue("Article Font is default", articleText_isDefault);
    settings->setValue("Article Font", current_articleText_font.family());
    settings->setValue("Article Font Size", articleText->font().pointSize());

    settings->setValue("Theme List Font is default", themeList_isDefault);
    settings->setValue("Theme List Font", current_themeList_font.family());
    settings->setValue("Theme List Font Size", themeList->font().pointSize());
    settings->endGroup();

    settings->beginGroup("windowParams");
    settings->setValue("Splitter's State", splitter->saveState());
    settings->setValue("Main Window Geometry", saveGeometry());
    settings->setValue("Preview checkbox is checked", settingsDialog->previewCheckbox->isChecked() );
    settings->endGroup();

}

void gseDialog::loadSettings()
{
    QString font1, font2;
    bool default1, default2;
    int size1, size2;

    settings->beginGroup("fonts");
    default1 = settings->value("Article Font is default").toBool();
    font1    = settings->value("Article Font").toString();
    size1    = settings->value("Article Font Size").toInt();

    default2 = settings->value("Theme List Font is default").toBool();
    font2    = settings->value("Theme List Font").toString();
    size2    = settings->value("Theme List Font Size").toInt();
    settings->endGroup();

    settings->beginGroup("windowParams");
    splitter->restoreState( settings->value("Splitter's State")    .toByteArray() );
    restoreGeometry(        settings->value("Main Window Geometry").toByteArray() );
    settingsDialog->previewCheckbox->setChecked(
                settings->value("Preview checkbox is checked").toBool());
    settings->endGroup();

    current_articleText_font = QFont( font1, size1 );
    current_themeList_font   = QFont( font2, size2 );

    articleText_isDefault = default1;
    themeList_isDefault   = default2;
    /*----------- Применение загруженных настроек -----------*/
    if( !articleText_isDefault)
        articleText->setFont(current_articleText_font);

    if( !themeList_isDefault)
        themeList->setFont(current_themeList_font);
}
